import numpy as np
import logging
from collections import deque
from typing import Optional, Tuple, Dict
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from response.BrainWaveResult import BrainWaveResult
from exception.base_exceptions import SignalProcessingException
from exception.exception_handler import global_exception_handler

logger = logging.getLogger(__name__)

class ThetaService:
    """
    Theta波段(4-8Hz)专用优化服务
    专注于Theta波段的科学化处理，不依赖其他过滤器
    """
    
    def __init__(self, history_size: int = 20, sampling_rate: float = 512.0):
        """
        初始化Theta服务
        
        Args:
            history_size: 历史数据缓存大小
            sampling_rate: 采样率 (Hz)
        """
        self.history_size = history_size
        self.sampling_rate = sampling_rate
        
        # 历史数据缓存
        self.theta_history = deque(maxlen=history_size)
        self.raw_theta_history = deque(maxlen=history_size)
        
        # 统计信息
        self.last_valid_theta = 0
        self.outlier_count = 0
        self.total_count = 0
        
        # 科学化的Theta波段参数 (基于脑电生理学)
        self.physiological_range = (500, 50000)    # 生理学合理范围
        self.normal_working_range = (2000, 25000)  # 正常工作状态范围
        self.max_change_rate = 0.3                 # 最大变化率 (30%/sample)
        
    def process_theta(self, brain_wave_result: BrainWaveResult) -> BrainWaveResult:
        """
        处理Theta波段数据 - 8频域增强版本
        
        利用8频域数据进行更精确的Theta波段分析，特别是结合相邻频段的信息
        来提高Theta波段处理的科学性和准确性。
        
        Args:
            brain_wave_result: 脑电数据容器（包含8频域数据）
            
        Returns:
            BrainWaveResult: 处理后的脑电数据容器
        """
        try:
            # 获取8频域原始数据
            raw_theta = brain_wave_result.theta
            raw_delta = brain_wave_result.delta
            raw_low_alpha = getattr(brain_wave_result, 'low_alpha', 0)
            raw_high_alpha = getattr(brain_wave_result, 'high_alpha', 0)
            poor_signal = brain_wave_result.poorSignal
            
            self.total_count += 1
            self.raw_theta_history.append(raw_theta)
            
            # 信号质量预检查
            if poor_signal > 100:  # 信号质量很差，使用安全回退值
                processed_theta = self.last_valid_theta if self.last_valid_theta > 0 else self._get_safe_fallback_value()
                status = "信号质量差，使用安全回退值"
            else:
                # 使用8频域增强的科学过滤算法
                processed_theta = self._enhanced_scientific_filter_8bands(
                    raw_theta, raw_delta, raw_low_alpha, raw_high_alpha
                )
                status = "8频域增强算法处理"
            
            # 更新历史记录
            self.theta_history.append(processed_theta)
            
            # 更新最后有效值
            if poor_signal <= 50 and self._is_physiologically_valid(processed_theta):
                self.last_valid_theta = processed_theta
            
            # 计算频段间相关性分析
            cross_band_analysis = self._analyze_cross_band_relationships(
                processed_theta, raw_delta, raw_low_alpha, raw_high_alpha
            )
            
            # 更新结果容器
            brain_wave_result.update_band('theta', processed_theta, f"ThetaService: {status}")
            brain_wave_result.add_processing_step('theta_8band_optimization', {
                'original_theta': raw_theta,
                'processed_theta': processed_theta,
                'status': status,
                'outlier_rate': (self.outlier_count / self.total_count * 100) if self.total_count > 0 else 0,
                'physiologically_valid': self._is_physiologically_valid(processed_theta),
                'cross_band_analysis': cross_band_analysis,
                'enhancement_factor': self._calculate_enhancement_factor(raw_theta, processed_theta)
            })
            
            return brain_wave_result
            
        except Exception as e:
            processing_error = SignalProcessingException(
                f"Theta 8频域处理失败: {str(e)}",
                signal_type="theta_8band_processing"
            )
            global_exception_handler.handle_exception(processing_error)
            return brain_wave_result
    
    def _get_safe_fallback_value(self) -> int:
        """获取安全的回退值"""
        if len(self.theta_history) > 0:
            # 使用最近几个有效值的中位数
            recent_values = list(self.theta_history)[-5:]
            return int(np.median(recent_values))
        else:
            # 使用生理学范围的安全中位数
            return int(np.mean(self.physiological_range))
    
    def _enhanced_scientific_filter_8bands(self, raw_theta: int, raw_delta: int, 
                                          raw_low_alpha: int, raw_high_alpha: int) -> int:
        """
        8频域增强的科学过滤算法
        
        利用相邻频段的信息来提高Theta波段处理的准确性：
        1. Delta波段(0.5-4Hz)与Theta波段(4-8Hz)的边界效应分析
        2. Low Alpha波段(8-10Hz)对Theta波段的影响评估
        3. 跨频段一致性检验和异常检测
        4. 基于频段间相关性的自适应滤波
        
        Args:
            raw_theta: 原始Theta值
            raw_delta: 原始Delta值
            raw_low_alpha: 原始Low Alpha值
            raw_high_alpha: 原始High Alpha值
            
        Returns:
            int: 8频域增强处理后的Theta值
        """
        # 1. 基础生理学范围检查
        if raw_theta < self.physiological_range[0] or raw_theta > self.physiological_range[1]:
            self.outlier_count += 1
            return self._get_safe_fallback_value()
        
        # 2. 跨频段一致性检验
        cross_band_consistency = self._check_cross_band_consistency(
            raw_theta, raw_delta, raw_low_alpha, raw_high_alpha
        )
        
        if not cross_band_consistency:
            self.outlier_count += 1
            # 使用相邻频段信息进行修正
            corrected_theta = self._cross_band_correction(
                raw_theta, raw_delta, raw_low_alpha
            )
            return corrected_theta
        
        # 3. 增强的变化率检查（考虑相邻频段）
        if len(self.theta_history) > 0:
            last_value = self.theta_history[-1]
            if last_value > 0:
                # 计算基础变化率
                change_rate = abs(raw_theta - last_value) / last_value
                
                # 根据相邻频段的变化调整容忍度
                adaptive_tolerance = self._calculate_adaptive_tolerance(
                    raw_delta, raw_low_alpha
                )
                
                if change_rate > adaptive_tolerance:
                    self.outlier_count += 1
                    # 使用8频域信息进行渐进调整
                    return self._adaptive_gradual_adjustment(
                        raw_theta, last_value, raw_delta, raw_low_alpha
                    )
        
        # 4. 增强的统计学异常检测
        if len(self.theta_history) >= 5:
            history_array = np.array(list(self.theta_history))
            z_score = self._calculate_z_score(raw_theta, history_array)
            
            # 根据频段间相关性调整Z-score阈值
            adaptive_threshold = self._calculate_adaptive_z_threshold(
                raw_delta, raw_low_alpha, raw_high_alpha
            )
            
            if z_score > adaptive_threshold:
                self.outlier_count += 1
                return self._get_safe_fallback_value()
        
        # 5. 应用8频域增强的平滑滤波
        return self._apply_8band_enhanced_smoothing(
            raw_theta, raw_delta, raw_low_alpha
        )
    
    def _scientific_filter(self, raw_theta: int) -> int:
        """传统科学过滤算法（向后兼容）"""
        # 1. 生理学范围检查
        if raw_theta < self.physiological_range[0] or raw_theta > self.physiological_range[1]:
            self.outlier_count += 1
            return self._get_safe_fallback_value()
        
        # 2. 变化率检查
        if len(self.theta_history) > 0:
            last_value = self.theta_history[-1]
            if last_value > 0:
                change_rate = abs(raw_theta - last_value) / last_value
                if change_rate > self.max_change_rate:
                    self.outlier_count += 1
                    # 使用渐进调整而非直接替换
                    max_change = int(last_value * self.max_change_rate)
                    if raw_theta > last_value:
                        return last_value + max_change
                    else:
                        return last_value - max_change
        
        # 3. 统计学异常检测
        if len(self.theta_history) >= 5:
            history_array = np.array(list(self.theta_history))
            z_score = self._calculate_z_score(raw_theta, history_array)
            if z_score > 3.0:  # 3-sigma规则
                self.outlier_count += 1
                return self._get_safe_fallback_value()
        
        # 4. 应用轻度平滑
        return self._apply_conservative_smoothing(raw_theta)
    
    def _calculate_z_score(self, value: float, data_array: np.ndarray) -> float:
        """计算Z-score"""
        if len(data_array) < 2:
            return 0
        
        mean = np.mean(data_array)
        std = np.std(data_array)
        
        if std == 0:
            return 0
        
        return abs(value - mean) / std
    
    def _apply_conservative_smoothing(self, raw_theta: int) -> int:
        """应用保守的平滑滤波"""
        if len(self.theta_history) < 2:
            return raw_theta
            
        # 使用较小的平滑系数以保持信号真实性
        alpha = 0.2  # 保守的平滑系数
        last_theta = self.theta_history[-1]
        smoothed = int(alpha * raw_theta + (1 - alpha) * last_theta)
        
        return smoothed
    
    def _is_physiologically_valid(self, theta_value: int) -> bool:
        """检查值是否在生理学合理范围内"""
        return self.physiological_range[0] <= theta_value <= self.physiological_range[1]
    
    def get_theta_trend(self) -> str:
        """获取Theta趋势分析"""
        if len(self.theta_history) < 5:
            return "数据不足"
        
        recent_values = list(self.theta_history)[-5:]
        trend_slope = np.polyfit(range(len(recent_values)), recent_values, 1)[0]
        
        if trend_slope > 100:
            return "上升趋势"
        elif trend_slope < -100:
            return "下降趋势"
        else:
            return "稳定"
    
    def _check_cross_band_consistency(self, theta: int, delta: int, 
                                    low_alpha: int, high_alpha: int) -> bool:
        """
        检查跨频段一致性
        
        基于脑电生理学原理，相邻频段应该表现出一定的相关性。
        异常的频段间比例可能表示伪迹或测量错误。
        """
        try:
            # 计算频段间比例
            if delta > 0:
                theta_delta_ratio = theta / delta
                # 正常情况下，Theta/Delta比例应在0.2-5.0之间
                if theta_delta_ratio < 0.1 or theta_delta_ratio > 10.0:
                    return False
            
            if low_alpha > 0:
                theta_alpha_ratio = theta / low_alpha
                # 正常情况下，Theta/Low_Alpha比例应在0.1-3.0之间
                if theta_alpha_ratio < 0.05 or theta_alpha_ratio > 8.0:
                    return False
            
            return True
            
        except (ZeroDivisionError, ValueError):
            return True  # 如果计算失败，假设一致性正常
    
    def _cross_band_correction(self, theta: int, delta: int, low_alpha: int) -> int:
        """基于相邻频段信息进行Theta值修正"""
        try:
            # 使用相邻频段的加权平均进行修正
            weights = []
            values = []
            
            if delta > 0 and self._is_physiologically_valid(delta):
                weights.append(0.3)  # Delta对Theta的影响权重
                values.append(delta * 0.8)  # 经验系数
            
            if low_alpha > 0 and self._is_physiologically_valid(low_alpha):
                weights.append(0.4)  # Low Alpha对Theta的影响权重
                values.append(low_alpha * 1.2)  # 经验系数
            
            if len(self.theta_history) > 0:
                weights.append(0.3)  # 历史值权重
                values.append(self.theta_history[-1])
            
            if weights:
                corrected_value = int(np.average(values, weights=weights))
                # 确保修正值在合理范围内
                return max(self.physiological_range[0], 
                          min(corrected_value, self.physiological_range[1]))
            else:
                return self._get_safe_fallback_value()
                
        except Exception:
            return self._get_safe_fallback_value()
    
    def _calculate_adaptive_tolerance(self, delta: int, low_alpha: int) -> float:
        """根据相邻频段计算自适应容忍度"""
        base_tolerance = self.max_change_rate
        
        # 如果相邻频段也在变化，增加容忍度
        if len(self.theta_history) > 0:
            try:
                # 这里简化处理，实际应用中可以更复杂
                if delta > 0 and low_alpha > 0:
                    # 如果相邻频段值较高，可能是整体脑电活动增强
                    activity_factor = (delta + low_alpha) / 20000  # 归一化
                    adaptive_factor = min(2.0, 1.0 + activity_factor * 0.5)
                    return base_tolerance * adaptive_factor
            except Exception:
                pass
        
        return base_tolerance
    
    def _adaptive_gradual_adjustment(self, raw_theta: int, last_value: int, 
                                   delta: int, low_alpha: int) -> int:
        """基于8频域信息的自适应渐进调整"""
        try:
            # 计算基础调整量
            max_change = int(last_value * self.max_change_rate)
            
            # 根据相邻频段信息调整变化幅度
            if delta > 0 and low_alpha > 0:
                # 如果相邻频段支持这种变化，允许更大的调整
                neighbor_support = min(1.5, (delta + low_alpha) / 15000)
                max_change = int(max_change * neighbor_support)
            
            if raw_theta > last_value:
                return min(raw_theta, last_value + max_change)
            else:
                return max(raw_theta, last_value - max_change)
                
        except Exception:
            return last_value
    
    def _calculate_adaptive_z_threshold(self, delta: int, low_alpha: int, 
                                      high_alpha: int) -> float:
        """计算自适应Z-score阈值"""
        base_threshold = 3.0
        
        try:
            # 如果相邻频段显示高活动，放宽阈值
            total_neighbor_activity = delta + low_alpha + high_alpha
            if total_neighbor_activity > 30000:  # 高活动状态
                return base_threshold * 1.2
            elif total_neighbor_activity < 5000:  # 低活动状态
                return base_threshold * 0.8
        except Exception:
            pass
        
        return base_threshold
    
    def _apply_8band_enhanced_smoothing(self, raw_theta: int, delta: int, 
                                      low_alpha: int) -> int:
        """应用8频域增强的平滑滤波"""
        if len(self.theta_history) < 2:
            return raw_theta
        
        try:
            # 基础平滑系数
            alpha = 0.2
            
            # 根据相邻频段调整平滑系数
            if delta > 0 and low_alpha > 0:
                # 如果相邻频段稳定，增加平滑
                neighbor_stability = 1.0 / (1.0 + abs(delta - low_alpha) / 10000)
                alpha = alpha * (0.5 + neighbor_stability * 0.5)
            
            last_theta = self.theta_history[-1]
            smoothed = int(alpha * raw_theta + (1 - alpha) * last_theta)
            
            return smoothed
            
        except Exception:
            return raw_theta
    
    def _analyze_cross_band_relationships(self, theta: int, delta: int, 
                                        low_alpha: int, high_alpha: int) -> Dict:
        """分析频段间关系"""
        analysis = {
            'theta_delta_ratio': 0.0,
            'theta_low_alpha_ratio': 0.0,
            'theta_high_alpha_ratio': 0.0,
            'frequency_dominance': 'unknown',
            'cross_band_coherence': 'normal'
        }
        
        try:
            if delta > 0:
                analysis['theta_delta_ratio'] = round(theta / delta, 3)
            
            if low_alpha > 0:
                analysis['theta_low_alpha_ratio'] = round(theta / low_alpha, 3)
            
            if high_alpha > 0:
                analysis['theta_high_alpha_ratio'] = round(theta / high_alpha, 3)
            
            # 判断频率主导性
            max_band = max(theta, delta, low_alpha, high_alpha)
            if max_band == theta:
                analysis['frequency_dominance'] = 'theta_dominant'
            elif max_band == delta:
                analysis['frequency_dominance'] = 'delta_dominant'
            elif max_band == low_alpha:
                analysis['frequency_dominance'] = 'low_alpha_dominant'
            else:
                analysis['frequency_dominance'] = 'high_alpha_dominant'
            
            # 评估跨频段一致性
            if self._check_cross_band_consistency(theta, delta, low_alpha, high_alpha):
                analysis['cross_band_coherence'] = 'coherent'
            else:
                analysis['cross_band_coherence'] = 'incoherent'
                
        except Exception:
            pass
        
        return analysis
    
    def _calculate_enhancement_factor(self, original: int, processed: int) -> float:
        """计算增强因子"""
        try:
            if original > 0:
                return round(processed / original, 3)
            return 1.0
        except Exception:
            return 1.0
    
    def reset_history(self):
        """重置历史数据"""
        self.theta_history.clear()
        self.raw_theta_history.clear()
        self.outlier_count = 0
        self.total_count = 0
        logger.info("ThetaService历史数据已重置")